Release 10.1A: OpenEdge Getting Started:
Object-oriented Programming
Errors within a constructor
There are two types of errors that can occur during the creation of an object:
- Instantiation error — The class file or a class file in the class hierarchy (source code or r-code) is not found on the
PROPATHor there is an incorrectly coded signature for one of the constructors in the class hierarchy. Progress automatically propagates this type of error to theNEWstatement that attempts to instantiate the object.- Application error — Your application logic encounters an abnormal condition in one of the constructors in the class hierarchy. You must programmatically propagate these errors back to the caller of the
NEWstatement that instantiates the object.Handling instantiation errors
If an error causes the Progress session not to instantiate the object, the error is automatically propagated back to the
Note: An improper signature can appear in a previously compiled class hierarchy if out-dated r-code for one of the classes is found and executed on theNEWstatement. There are several reasons why the session might not be able to instantiate an object. One of the constructors in the class hierarchy might not have the proper signature (mismatched number of parameters, or mismatched data type of a parameter), for example. In this case, when the Progress session determines that it cannot invoke a constructor because of one of these errors, the error cannot be handled on theSUPERstatement that invoked the constructor, but instead can only be handled by theNEWstatement that instantiated the object. For this reason, it is illegal to putNO-ERRORon theSUPERstatement.PROPATH. Thus, you must ensure that all classes in a class hierarchy are properly compiled. For more information, see the "Compiling class files" section.When the Progress session encounters an instantiation error, it raises
ERRORon theNEWstatement and sets the object reference to the Unknown value (?). How an application handles this error is thus controlled by theNEWstatement.The following example (
instantiater1.p) assumes that the classDerivedcannot be instantiated because the signature of one of its constructors is invalid. In this case, Progress setsrDerivedto the Unknown value (?) and sets theERRORSTATUSsystem handle with the corresponding error information, as shown:
In
instantiater1.p, Progress knows that the object has not been instantiated at all. Progress sets the object reference (rDerived) to the Unknown value (?) and does not invoke any of the class destructors. This is because Progress also knows that none of the corresponding constructors in the class hierarchy had an opportunity to run successfully. The procedure then checks theERROR-STATUSsystem handle to verify the success of theNEWstatement, and proceed accordingly.Handling application errors
When an application determines that the instantiation process is not proceeding properly because of an application error, it is obligated to inform the caller of this condition from the constructor. The same restrictions on returning an error from a method also apply to constructors. This means that during the object instantiation process, if the constructor is unable to perform its function to either populate the object's data members or perform any other object initialization task, it must return status information to the caller using an output parameter, setting a public data member, or using some other technique, in order to convey this error state.
The previous section shows examples of setting an output parameter to handle errors in methods (see the "Errors within a method" section). You can use a similar mechanism to indicate an error in a constructor.
In the following examples (
Base.clsandDerived.cls), one object (Derived) inherits behavior from another object (Base). In this instance, theBaseconstructor fails to initialize properly because theFINDstatement fails to return a record:
In
instantiater2.p, the Progress session does not know that the object failed to instantiate properly. Therefore, Progress providesrDerivedwith a valid object reference. The only reason that the caller knows that the instantiation process failed, is that each class in the hierarchy propagates thebSuccessoutput parameter back to theNEWstatement.Using this model, every level of the class hierarchy must define a constructor output parameter and pass up the status value all the way to the
NEWstatement. This can be cumbersome in a class hierarchy with many levels, where you might want to use an alternative.As one alternative, you can terminate the instantiation process by deleting the object being instantiated from within a constructor during the instantiation process. If a constructor invokes the
DELETEOBJECTTHIS-OBJECTstatement, the Progress session interprets this statement as an application request to terminate the instantiation process. When the constructor that invokedDELETEOBJECTcompletes, the Progress session does not continue to execute the calling constructor (the constructor whoseSUPERstatement invoked the super class constructor that failed). Instead, Progress terminates the remaining constructors on the call stack and continues from theNEWstatement that invoked them.In this situation, the Progress session sets the object reference assigned by the
NEWstatement to the Unknown value (?), but does not raiseERROR. In addition, the Progress session executes all of the destructors for all of the classes in the hierarchy that executed prior to the constructor that invoked theDELETEOBJECTstatement. This gives each initialized class in the hierarchy an opportunity to free any resources that its corresponding constructor might have allocated.In the following example,
instantiater3.p, assume that the classDerivedcannot be instantiated because one of its constructors calledDELETEOBJECTTHIS-OBJECT. Progress setsrDerivedto the Unknown value (?), but does not setERROR-STATUSsystem handle, as shown:
In
instantiater3.p, Progress knows that the object has not been instantiated. Therefore, it sets the object reference (rDerived) to the Unknown value (?) and invokes the destructor for any class in the hierarchy whose constructor executed completely.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |